﻿// eSystem.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>

#include <type_traits>

#include "registers.h"
#include "options.h"
#include "hex_loader.h"
#include "object.h"
#include "reflect.h"

using namespace rft;

template <typename T, int N>
void print(T(&array)[N]) {
	for (auto&& i : array) {
		std::printf("0x%X, ", i);
	}
	std::printf("\n");
}

struct test: public object {
	reflect_class(test);

public:
	int _value[2][3];
	const char* name = typeid(typename std::remove_all_extents_t<decltype(_value)>).name();

public:
	std::string to_string() const override {
		using namespace std::string_literals;
		std::string lower = object::to_string();
		std::transform(lower.begin(), lower.end(), lower.begin(),
					   [](auto&& c) { return std::toupper(c); } 
		);
		return "0x"s + lower;
	}
};


template <typename T>
struct base_type {
	reflect_class(T);
};

base_type<int> base_type_int;
base_type<char> base_type_char;
base_type<float> base_type_float;
base_type<std::string> base_type_string;

void print_size(const std::string &type) {
	using namespace std::string_literals;
	auto result = rft::reflect_helper::get_reflect_table().find(type.c_str());

	if (result == rft::reflect_helper::get_reflect_table().end()) {
        printf("type error!\n");
	} else {
		printf(("sizeof("s + type + ") = %d\n"s).c_str(), result->second.size);
	}
}

int main(int argc, char *argv[]) {
	auto rom = hex_loader{}.load("C:\\Users\\26066\\Desktop\\保存\\hairdry-shop\\51lessons\\src\\cc.hex", options::ROM_SIZE);

	printf("0x%X\r\n", rom.size());

    /*
	for (size_t i = 0; i < rom.size(); i += 8) {
		printf("[%04XH - %04XH] : %016llXH\t", i, i + 7, sf_register<64>{ &rom, i }.read());
		if ((i / 8) % 2 == 1) printf("\r\n");
	}
    */

	object* obj = new test;

	puts(obj->to_string().data());
	puts(obj->get_class_name().data());

	puts((dynamic_cast<test*>(obj))->name);

	float a;

	puts(object::get_class_name(a).data());
	puts(object::get_class_name(object{}).data());
	puts(object::get_class_name(*obj).data());
	puts(object::get_class_name(obj).data());

	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
